package com.xinyue.ext.reader.dao;

import org.dom4j.Element;

import com.xinyue.ext.EnumData;
import com.xinyue.ext.Label;
import com.xinyue.ext.data.FinderData;
import com.xinyue.ext.exception.BeanException;
import com.xinyue.ext.exception.FinderException;
import com.xinyue.ext.reader.ParamHolder;
import com.xinyue.ext.util.StringUtil;

public abstract class DaoContext implements Label, EnumData{
	//参数集
	protected static ParamHolder holder;
	
	/**读取查询信息
	 */
	public abstract void read(Element finder) throws FinderException;
	
	/**
	 * 读取公共属性
	 * @param e
	 * @return
	 * @throws BeanException
	 */
	protected FinderData commonRead(Element e) throws FinderException {
		FinderData find = new FinderData();
		
		//方法名称
		find.setMethod(methodOprate(e.attributeValue(method_)));
		
		return find;
	}
	
	/**验证方法:方法名称不能为空
	 * 当前验证不支持对方法名相同，参数相同的验证。对字符长度没有限制。
	 */
	private String methodOprate(String method) throws FinderException {
		if(StringUtil.isNull(method)) {
			throw new FinderException("query/hql/sql标签必须定义method属性", holder.getException());
		}
		return method;
	}
	
	
	/**
	 * 验证返回值类型是否正确
	 * @param type
	 * @param flag
	 * @throws FinderException
	 */
	protected void returnType(String type, FinderData find, int flag) throws FinderException {
		//共有属性
		if(returnQuery[0].equals(type)) {//Bean
			find.setConvert(true);
			find.setOnly(true);
			find.setReturnType(holder.getEntity().getClassName());
		}else if(returnQuery[1].equals(type)) {//List
			find.setWarning(true);
			find.setReturnType("List<" + holder.getEntity().getClassName() + ">");
		}else if(returnQuery[2].equals(type)) {//Count
			find.setConvert(true);
			find.setOnly(true);
			find.setReturnType("Integer");
		}
		if(flag == query_type && find.getReturnType() == null) {
			throw new FinderException("query标签returnType属性值不合法:" + type, holder.getException());
		}
		
		//引用类型
		if(returnQL[0].equals(type)) {//Map
			holder.getDaoImpt().add("java.util.Map");
			find.setReturnType("Map<String, Object>");
		}else if(returnQL[1].equals(type)) {//List<Object[]>
			find.setWarning(true);
			find.setReturnType(type);
		}else if(returnQL[2].equals(type)) {//Object[]
			find.setConvert(true);
			find.setOnly(true);
			find.setReturnType(type);
		}
		
		//Java type
		if(returnJava[0].equals(type)) {//Date
			holder.getDaoImpt().add("java.util.Date");
			find.setConvert(true);
			find.setOnly(true);
			find.setReturnType(type);
		}else if(returnJava[1].equals(type)) {//BigDecimal
			holder.getDaoImpt().add("java.math.BigDecimal");
			find.setConvert(true);
			find.setOnly(true);
			find.setReturnType(type);
		}else if(returnJava[2].equals(type)) {//Blob
			holder.getDaoImpt().add("java.sql.Blob");
			find.setConvert(true);
			find.setOnly(true);
			find.setReturnType(type);
		}else {
			for (int i = 3; i < returnJava.length; i++) {
				if(returnJava[i].equals(type)) {
					find.setConvert(true);
					find.setOnly(true);
					find.setReturnType(type);
				}
			}
		}
		
		//List
		if(returnList[0].equals(type)) {//List<Date>
			holder.getDaoImpt().add("java.util.Date");
			find.setWarning(true);
			find.setReturnType(type);
		}else if(returnList[1].equals(type)) {//List<BigDecimal>
			holder.getDaoImpt().add("java.math.BigDecimal");
			find.setWarning(true);
			find.setReturnType(type);
		}else {
			for (int i = 2; i < returnList.length; i++) {
				if(returnList[i].equals(type)) {
					find.setWarning(true);
					find.setReturnType(type);
				}
			}
		}
		
		if(find.getReturnType() == null) {
			throw new FinderException("hql/sql标签returnType属性值不合法:" + type, holder.getException());
		}
	}
	
	/**
	 * Java基本类型验证并返回符合hibernate规范的setter语句
	 * @throws FinderException
	 */
	protected String setterOperate(String name, String type) {
		if(javaType[0].equals(type)) {//Date
			holder.getDaoImpt().add("java.util.Date");
			return "q.setDate(\"" + name + "\", " + name + ");";
		}else if(javaType[1].equals(type)) {//BigDecimal
			holder.getDaoImpt().add("java.math.BigDecimal");
			return "q.setBigDecimal(\"" + name + "\", " + name + ");";
		}else if(javaType[3].equals(type)) {//String
			return "q.setString(\"" + name + "\", " + name + ");";
		}else if(javaType[4].equals(type)) {//boolean
			return "q.setBoolean(\"" + name + "\", " + name + ");";
		}else if(javaType[5].equals(type)) {//int
			return "q.setInteger(\"" + name + "\", " + name + ");";
		}else if(javaType[6].equals(type)) {//double
			return "q.setDouble(\"" + name + "\", " + name + ");";
		}else if(javaType[7].equals(type)) {//long
			return "q.setLong(\"" + name + "\", " + name + ");";
		}else if(javaType[8].equals(type)) {//float
			return "q.setFloat(\"" + name + "\", " + name + ");";
		}else if(javaType[9].equals(type)) {//byte
			return "q.setByte(\"" + name + "\", " + name + ");";
		}else if(javaType[10].equals(type)) {//short
			return "q.setShort(\"" + name + "\", " + name + ");";
		}else if(javaType[11].equals(type)) {//char
			return "q.setCharacter(\"" + name + "\", " + name + ");";
		}
		
		return null;
	}
}
